home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
biged.zip
/
BIGED.IN1
< prev
next >
Wrap
Text File
|
1990-12-12
|
50KB
|
1,838 lines
{***************************************}
{* BIGED.IN1 1.03 *}
{* (part of BIGED.PAS) *}
{***************************************}
function BigEditor.beOfsWhite(P : LinePtr) : Byte;
var B : Byte;
begin
beOfsWhite := 0;
if P^.lnLen = 0 then exit;
B := 0;
while (B <= Byte(P^.St^[0])) and (P^.St^[B+1] = ' ') do
Inc(B);
beOfsWhite := B;
end;
procedure BigEditor.beResetSplit;
var
I : Integer;
begin
CurTopIdx := EList.Num(CurTop);
I := CurLineOfs;
if I > Height-1 then
I := Height-1;
CurLine := CurTop;
CurLineOfs := 0;
beLineDown(I);
end;
procedure BigEditor.beReAlign;
var
N : LinePtr;
I : Integer;
begin
CurTopIdx := EList.Num(CurTop);
N := CurTop;
I := 0;
while (I < Height-1) and (CurLine <> N) do begin
N := LinePtr(N^.dlNext);
Inc(I);
end;
if I = Height-1 then
CurLine := LinePtr(N^.dlPrev);
CurLineOfs := I;
end;
procedure BigEditor.beRealignDown;
var
N : LinePtr;
I : Integer;
begin
CurTopIdx := EList.Num(CurTop);
N := CurTop;
I := 0;
while (N^.dlNext <> nil) and (CurLine <> N) do begin
N := LinePtr(N^.dlNext);
Inc(I);
if I > Height-1 then begin
CurTop := LinePtr(CurTop^.dlNext);
Inc(CurTopIdx);
end;
end;
if I >= Height-1 then
CurLineOfs := Height-1
else
CurLineOfs := I;
end;
procedure BigEditor.beDeleteLinePrim(P : LinePtr);
var Q,T : LinePtr;
IsBetween : Boolean;
InVis : Boolean;
W : Integer;
begin
T := P;
with EList do begin
if T^.dlNext = NIL then
T^.lnUpdate('')
else begin
if T = CurTop then begin
CurTop := LinePtr(CurTop^.dlNext);
if T = CurLine then
CurLine := LinePtr(CurLine^.dlNext)
else
Dec(CurLineOfs);
end
else if T = CurLine then
CurLine := LinePtr(CurLine^.dlNext)
else begin
IsBetween := False;
InVis := False;
Q := CurTop;
for W := 1 to Height do begin
if Q = T then InVis := True;
if (Q = CurLine) and (InVis) then IsBetween := True;
if Q <> NIL then
Q := LinePtr(Next(Q));
end;
if IsBetween then
Dec(CurLineOfs);
end;
beLineDeleted(T);
EList.Delete(T);
end;
end;
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beCharsInserted(LP : LinePtr; Count : Integer);
var I : Integer;
procedure FixMarker(var MR : MarkerRec; IsEnd,IsTextMarker : Boolean);
var T : Integer;
begin
with MR do
if (Line = LP) and (Col >= COfs+XOfs) then begin
T := Col;
if (IsTextMarker) or
((IsEnd) and (T+1 >= COfs+XOfs)) or
(T > COfs+XOfs) then
Inc(T, Count);
if T < COfs+XOfs then
Col := COfs+XOfs
else
Col := T;
end;
end;
begin
if LP = BkTop.Line then FixMarker(BkTop,False,False);
if LP = BkBot.Line then FixMarker(BkBot,True,False);
beCheckBlock;
if NOT beOptionsAreOn(beBlockOK) then
beOptionsOff(beBlockOn);
if MarkerFlags <> 0 then
for I := 0 to MaxMarker do
if LP = Markers[i].Line then
FixMarker(Markers[i],False,True);
end;
procedure BigEditor.beLineDeleted(P : LinePtr);
var I : Integer;
begin
if P = BkTop.Line then begin
if P = BkBot.Line then begin
beResetMarkers(False);
beOptionsOff(beBlockOn);
end
else begin
IncPtr(BkTop.Line,1);
Inc(BkTop.LNum);
BkTop.Col := 1;
end;
end
else if P = BkBot.Line then begin
IncPtr(BkBot.Line,1);
Inc(BkBot.LNum);
BkBot.Col := 0;
end
else begin
I := EList.Num(P);
if I < BkTop.LNum then begin
Dec(BkTop.LNum);
Dec(BkBot.LNum);
end
else if I < BkBot.LNum then
Dec(BkBot.LNum);
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
end;
if MarkerFlags <> 0 then
for I := 0 to MaxMarker do
if Markers[i].Line = P then
Markers[i].Line := NIL;
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beBreakLine(At : Integer);
var L : LinePtr;
P : LinePtr;
I : Integer;
B : Byte;
procedure FixMarker(var MR : MarkerRec; IsEnd : Boolean);
begin
with MR do if Line <> nil then
if ((IsEnd) and (Col <= At)) or
(Col >= At) then begin
IncPtr(Line,1);
Inc(LNum);
Col := Col-At+1;
end;
end;
begin
Tmp := '';
B := 1;
P := CurLine;
{place our new line in the stream}
New(L,Init(''));
EList.Place(L,P);
{fixup blocking}
if P = BkTop.Line then begin
FixMarker(BkTop,False);
if P = BkBot.Line then
FixMarker(BkBot,True);
end
else if P = BkBot.Line then
FixMarker(BkBot,True)
else begin
I := CurTopIdx+CurLineOfs;
if I < BkTop.LNum then begin
Inc(BkTop.LNum);
Inc(BkBot.LNum);
end
else if I < BkBot.LNum then
Inc(BkBot.LNum);
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
end;
if MarkerFlags <> 0 then
for I := 1 to MaxMarker do
if Markers[i].Line = P then
FixMarker(Markers[i],False);
if At <= P^.lnLen then begin
{split the line}
Tmp := Copy(Current,At,Length(Current));
Delete(Current,At,Length(Current));
P^.lnUpdate(Current);
end;
{add padding if nessessary}
if beOptionsAreOn(beIndent) then begin
B := beOfsWhite(P);
if B > 0 then
Insert(CharStr(' ',B),Tmp,1);
end;
L^.lnUpdate(Tmp);
beLineDown(1);
beCursorHome;
beCursorRight(B);
beCharsInserted(CurLine,B);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beWrapLine;
var L : LinePtr;
P : LinePtr;
I : Integer;
B : Byte;
procedure FixMarker(var MR : MarkerRec; At : Integer);
begin
with MR do if Line <> nil then
if Col >= At then begin
IncPtr(Line,1);
Inc(LNum);
Col := Col-At+1;
end;
end;
begin
Tmp := '';
B := 1;
P := CurLine;
{place our new line in the stream}
New(L,Init(''));
EList.Place(L,P);
WordWrap(Current,Current,Tmp,Margin,False);
P^.lnUpdate(Current);
{fixup blocking}
if P = BkTop.Line then begin
FixMarker(BkTop,Length(Current)+1);
if P = BkBot.Line then
FixMarker(BkBot,Length(Current)+1);
end
else if P = BkBot.Line then
FixMarker(BkBot,Length(Current)+1)
else begin
I := CurTopIdx+CurLineOfs;
if I < BkTop.LNum then begin
Inc(BkTop.LNum);
Inc(BkBot.LNum);
end
else if I < BkBot.LNum then
Inc(BkBot.LNum);
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
end;
if MarkerFlags <> 0 then
for I := 1 to MaxMarker do
if Markers[i].Line = P then
FixMarker(Markers[i],Length(Current)+1);
{add padding if nessessary}
if beOptionsAreOn(beIndent) then begin
Tmp := Trim(Tmp);
B := beOfsWhite(P);
if B > 0 then
Insert(CharStr(' ',B),Tmp,1);
end;
L^.lnUpdate(Tmp);
beLineDown(1);
beCursorHome;
beCursorRight(Length(Tmp));
beCharsInserted(CurLine,Length(Tmp));
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beJoinLines(LP : LinePtr);
var L,P : LinePtr;
I,J : Integer;
procedure FixMarker(var MR : MarkerRec; PrevLen : Integer);
begin
with MR do if Line <> NIL then begin
DecPtr(Line,1);
Dec(LNum);
Col := Col + PrevLen;
end;
end;
begin
P := LP;
L := LinePtr(P^.dlNext);
if L = NIL then exit;
J := P^.lnLen;
P^.lnUpdate(P^.lnReturn+L^.lnReturn);
{fixup blocking}
if P = BkTop.Line then begin
FixMarker(BkTop,J);
if P = BkBot.Line then
FixMarker(BkBot,J);
end
else if P = BkBot.Line then
FixMarker(BkBot,J)
else begin
I := EList.Num(P);
if I < BkTop.LNum then begin
Dec(BkTop.LNum);
Dec(BkBot.LNum);
end
else if I < BkBot.LNum then
Dec(BkBot.LNum);
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
end;
if MarkerFlags <> 0 then
for I := 0 to MaxMarker do
if Markers[i].Line = L then
FixMarker(Markers[i],J);
EList.Delete(L);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beTabOver;
var P : LinePtr;
N,W : Integer;
begin
if beOptionsAreOn(beSmartTabs) then begin
W := COfs+XOfs;
P := CurLine;
DecPtr(P,1);
if (P = NIL) or (W > P^.lnLen) then
IncPtr(P,2);
if (P <> NIL) and (W <= P^.lnLen) then begin
Tmp := P^.lnReturn;
N := W;
while (W <= Length(Tmp)) and (Tmp[w] <> ' ') do
Inc(W);
while (W <= Length(Tmp)) and (Tmp[w] = ' ') do
Inc(W);
if W > N then begin
if N <= Length(Current) then begin
Insert(CharStr(' ',W-N),Current,N);
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine,W-N);
SetLongFlag(beOptions,beModified);
end;
beCursorRight(W-N);
end;
end;
end
else if beDefTabDelta > 0 then begin
W := beDefTabDelta - ((COfs+XOfs) mod beDefTabDelta);
if W = 0 then W := beDefTabDelta;
if COfs+XOfs <= Length(Current) then begin
Insert(CharStr(' ',W),Current,COfs+XOfs);
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine,W);
SetLongFlag(beOptions,beModified);
end;
beCursorRight(W);
end;
end;
procedure BigEditor.beInsertChar(C : Char);
{insert a character into the stream}
var W : Byte absolute Current;
B,L : Byte;
S : String;
P : LinePtr;
begin
if COfs+XOfs >= 255 then exit;
if W < (COfs+XOfs) then begin
Current := Pad(Current,COfs+XOfs-1) + C;
beCharsInserted(CurLine,COfs+XOfs-W);
end
else if LongFlagIsSet(beOptions,beInsert) then begin
Insert(C,Current,COfs+XOfs);
beCharsInserted(CurLine,1);
end
else
Current[COfs+XOfs] := C;
CurLine^.lnUpdate(Current);
beCursorRight(1);
SetLongFlag(beOptions,beModified);
{if we're wrapping, do so here}
if (beOptionsAreOn(beWordWrap)) and
(COfs+XOfs > Margin+1) and
(C <> ' ') then
beWrapLine;
end;
procedure BigEditor.beNewLine(MoveDown : Boolean);
{-insert a new line below the current}
var
L : LinePtr;
I : Integer;
begin
if NOT LongFlagIsSet(beOptions,beInsert) then begin
beLineDown(1);
COfs := 1;
XOfs := 0;
end
else if NOT(MoveDown) then begin
I := COfs+XOfs;
beBreakLine(CurLine^.lnLen+1);
beLineUp(1);
beCursorHome;
beCursorRight(I-1);
end
else
beBreakLine(COfs+XOfs);
end;
procedure BigEditor.beBackspace;
{-backspace over the previous character}
var
I : Integer;
begin
if (COfs+XOfs > 1) then begin
if (COfs+XOfs) <= (CurLine^.lnLen+1) then begin
System.Delete(Current,COfs+XOfs-1,1);
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine, -1);
SetLongFlag(beOptions,beModified);
end;
beCursorLeft(1);
end
else if CurLine^.dlPrev <> NIL then begin
beLineUp(1);
I := CurLine^.lnLen;
beJoinLines(CurLine);
beCursorHome;
beCursorRight(I);
beForceRedraw := True;
SetLongFlag(beOptions,beModified);
end;
end;
procedure BigEditor.beDeleteCharAtCursor;
{-delete the current character}
begin
if (COfs+XOfs) <= Length(Current) then begin
System.Delete(Current,COfs+XOfs,1);
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine,-1);
SetLongFlag(beOptions,beModified);
end
else if beOptionsAreOn(beDeleteJoins) then begin
if Length(Current) < COfs+XOfs-1 then
CurLine^.lnUpdate(Pad(Current,COfs+XOfs-1));
beJoinLines(CurLine);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
end;
procedure BigEditor.beWordLeft;
{-jump to the start of the previous word}
var W : Byte absolute Current;
X,N : Integer;
Cl : CharClass;
begin
if COfs+XOfs > 1 then begin
if W < (COfs+XOfs) then begin
if COfs+XOfs{W} >= WinWidth then begin
COfs := WinWidth;
XOfs := W - WinWidth + 1;
beForceRedraw := True;
end
else begin
COfs := W+1;
XOfs := 0;
end;
end;
X := COfs+XOfs;
N := X;
while (X > 1) and (GetClass(Current[x-1]) <> Alpha) do
Dec(x);
while (X > 1) and (GetClass(Current[x-1]) = Alpha) do
Dec(x);
beCursorLeft(N-X);
end
else if CurLine^.dlPrev <> NIL then begin
beLineUp(1);
beCursorEOL;
end;
end;
procedure BigEditor.beWordRight;
{-jump to the start of the next word}
var W : Byte Absolute Current;
N,X : Integer;
begin
if (COfs+XOfs > W) and (CurLine^.dlNext <> NIL) then begin
beLineDown(1);
beCursorHome;
end
else begin
X := COfs+XOfs;
N := X;
while (X <= W) and NOT(Current[x] in beWordDelims) do
Inc(X);
while (X <= W) and (Current[x] in beWordDelims) do
Inc(X);
beCursorRight(X-N);
end;
end;
procedure BigEditor.beDeleteWordRight;
{-delete the current word}
var
P : LinePtr;
W,X,I : Integer;
Sl : Byte absolute Current;
ChClass : CharClass;
begin
X := XOfs+COfs;
if (Sl < X) and (CurLine^.dlNext <> NIL) then
beJoinLines(CurLine)
else begin
W := X;
if Current[w] <> ' ' then begin
ChClass := GetClass(Current[w]);
while (W <= Sl) and (GetClass(Current[w]) = ChClass) do
Inc(W);
end;
while (W <= Sl) and (GetClass(Current[w]) = Blank) do
Inc(W);
I := W-X;
if W > X then begin
System.Delete(Current,X,I);
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine,-I);
SetLongFlag(beOptions,beModified);
end;
end;
end;
procedure BigEditor.beDeleteToEndOfLine;
{-delete the rest of the current line}
var I : Integer;
begin
if (COfs+XOfs) <= Length(Current) then begin
I := Length(Current) - (COfs+XOfs);
System.Delete(Current,COfs+XOfs,Length(Current));
CurLine^.lnUpdate(Current);
beCharsInserted(CurLine,-I);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
end;
procedure BigEditor.beSaveStreamState(var S : StreamStateRec;
SaveBlocking : Boolean);
begin
with S do begin
SaveCurTopIdx := CurTopIdx;
SaveCurLineOfs := CurLineOfs;
SaveCOfs := COfs;
SaveXOfs := XOfs;
SaveFlags := beOptions;
if SaveBlocking then begin
SaveBkTop := BkTop;
SaveBkBot := BkBot;
SaveMarkers := Markers;
end
else begin
FillChar(SaveBkTop,SizeOf(SaveBkTop),0);
SaveBkBot := SaveBkBot;
FillChar(SaveMarkers,SizeOf(SaveMarkers),0);
end;
end;
end;
procedure BigEditor.beRestoreStreamState(var S : StreamStateRec;
RestoreBlocking : Boolean);
var I : Integer;
begin
beResetLineList;
with S do begin
CurTop := LinePtr(EList.Nth(SaveCurTopIdx));
CurLine := CurTop;
CurTopIdx := SaveCurTopIdx;
CurLineOfs := SaveCurLineOfs;
I := 0;
while I <> CurLineOfs do begin
CurLine := LinePtr(CurLine^.dlNext);
Inc(I);
end;
COfs := SaveCOfs;
XOfs := SaveXOfs;
beOptions := beOptions or (SaveFlags and not BadBigEdOptions);
if RestoreBlocking then begin
BkTop := SaveBkTop;
BkTop.Line := LinePtr(EList.Nth(BkTop.LNum));
BkBot := SaveBkBot;
BkBot.Line := LinePtr(EList.Nth(BkBot.LNum));
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
beOptionsOn(beBlockOn);
end;
Markers := SaveMarkers;
for I := 0 to MaxMarker do
Markers[i].Line := LinePtr(EList.Nth(Markers[i].LNum));
end;
end;
beForceRedraw := True;
end;
{----------------------- Block-oriented operations -------------------------}
procedure BigEditor.beClearBlocking;
var P : LinePtr;
begin
with EList do begin
P := LinePtr(Head);
while P <> NIL do begin
P^.lnFlagsOff(IsBlocked);
P := LinePtr(P^.dlNext);
end;
ClearLongFlag(beOptions,beBlockOK);
end;
end;
procedure BigEditor.beConnectMarks;
var P : LinePtr;
begin
P := BkTop.Line;
if P = NIL then
beClearBlocking
else if BkBot.Line <> NIL then begin
P^.lnFlagsOn(IsBlocked);
while (P <> nil) and (P <> BkBot.Line) do begin
P^.lnFlagsOn(IsBlocked);
P := LinePtr(P^.dlNext);
end;
if P <> nil then begin
P^.lnFlagsOn(IsBlocked);
SetLongFlag(beOptions,beBlockOK);
end
else
beClearBlocking;
end;
end;
function BigEditor.beLineInBlock(P : LinePtr) : Boolean;
var N : LinePtr;
begin
beLineInBlock := True;
N := BkTop.Line;
while (N <> nil) and (N <> BkBot.Line) do begin
if N = P then exit;
N := LinePtr(N^.dlNext);
end;
beLineInBlock := (P = BkBot.Line);
end;
procedure BigEditor.beSetBkTop;
begin
with BkTop do begin
Line := CurLine;
LNum := CurTopIdx+CurLineOfs;
Col := COfs+XOfs;
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
beOptionsOn(beBlockOn);
end
else beOptionsOff(beBlockOn);
beForceRedraw := True;
end;
procedure BigEditor.beSetBkBot;
begin
with BkBot do begin
Line := CurLine;
LNum := CurTopIdx+CurLineOfs;
Col := Pred(COfs+XOfs);
end;
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beConnectMarks;
beOptionsOn(beBlockOn);
end
else beOptionsOff(beBlockOn);
beForceRedraw := True;
end;
procedure BigEditor.beCheckBlock;
var P : LinePtr;
begin
ClearLongFlag(beOptions,beBlockOK);
{if no markers defined, exit}
if (BkTop.Line = NIL) or (BkBot.Line = NIL) then exit;
{if same line but mismatched columns, exit}
P := BkTop.Line;
if (P = BkBot.Line) then
if BkTop.Col >= BkBot.Col then exit;
{scan forward, looking for BkBot}
with EList do while P <> NIL do begin
if P = BkBot.Line then begin
SetLongFlag(beOptions,beBlockOK);
exit;
end;
P := LinePtr(Next(P));
end;
end;
function BigEditor.beStoreBlock(var ToList : LineList) : Boolean;
label Skip;
var P,N : LinePtr;
begin
beStoreBlock := False;
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) or
(NOT(beOptionsAreOn(beBlockOn))) then exit;
SBkTop := BkTop;
SBkBot := BkBot;
ToList.Clean;
P := BkTop.Line;
if BkTop.Line = BkBot.Line then begin
Tmp := Copy(P^.lnReturn,BkTop.Col,BkBot.Col-BkTop.Col+1);
New(N,Init(Tmp));
if N = NIL then goto Skip;
ToList.Append(N);
beStoreBlock := True;
exit;
end
else begin
Tmp := Copy(P^.lnReturn,BkTop.Col,P^.lnLen);
New(N,Init(Tmp));
if N = NIL then goto Skip;
ToList.Append(N);
P := LinePtr(EList.Next(P));
while P <> BkBot.Line do begin
New(N,Init(P^.lnReturn));
if N = NIL then goto Skip;
ToList.Append(N);
P := LinePtr(EList.Next(P));
end;
Tmp := Copy(BkBot.Line^.lnReturn,1,BkBot.Col);
if TrimLead(Tmp) = '' then Tmp := '';
New(N,Init(Tmp));
if N = NIL then goto Skip;
ToList.Append(N);
beStoreBlock := True;
exit;
end;
Skip:
GotError(epNonFatal+ecOutofMemory,'Out of memory');
ToList.Clean;
end;
procedure BigEditor.beCopyBlock;
var N,O,P : LinePtr;
S : String;
begin
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) or
(NOT(beOptionsAreOn(beBlockOn))) then exit;
SBkTop := BkTop;
SBkBot := BkBot;
if BkTop.Line = BkBot.Line then begin
S := Copy(BkTop.Line^.St^,BkTop.Col,BkBot.Col-BkTop.Col+1);
Tmp := CurLine^.St^;
if COfs+XOfs > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1) + S
else
Insert(S,Tmp,COfs+XOfs);
CurLine^.lnUpdate(Tmp);
{update blocking}
BkTop.Line^.lnFlagsOff(IsBlocked);
BkTop.Line := CurLine;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkTop.Col := COfs+XOfs;
BkBot := BkTop;
BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
CurLine^.lnFlagsOn(IsBlocked);
end
else begin
N := BkTop.Line;
P := CurLine;
Tmp := P^.lnReturn;
{if needed, split the current line}
if COfs+XOfs <= Length(Tmp) then begin
S := Copy(Tmp,COfs+XOfs,Length(Tmp));
Delete(Tmp,COfs+XOfs,Length(Tmp));
end
else begin
if COfs+XOfs-1 > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1);
S := '';
end;
{set BlockTop to our new starting point}
BkTop.Line := P;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkBot.LNum := BkTop.LNum;
BkTop.Col := COfs+XOfs;
{walk the list, inserting lines}
Tmp := P^.St^ + N^.St^;
P^.lnUpdate(Tmp);
N^.lnFlagsOff(IsBlocked);
N := LinePtr(N^.dlNext);
while N <> BkBot.Line do begin
New(O,Init(N^.St^));
O^.lnFlagsOn(IsBlocked);
EList.Place(O,P);
P := LinePtr(P^.dlNext);
N^.lnFlagsOff(IsBlocked);
N := LinePtr(N^.dlNext);
Inc(BkBot.LNum);
end;
{fixup the last line}
Tmp := Copy(N^.lnReturn,1,BkBot.Col);
N^.lnFlagsOff(IsBlocked);
BkBot.Col := Length(Tmp);
if S <> '' then Tmp := Tmp + S;
New(O,Init(Tmp));
O^.lnFlagsOn(IsBlocked);
EList.Place(O,P);
P := LinePtr(P^.dlNext);
Inc(BkBot.LNum);
BkBot.Line := P;
BkTop.Line^.lnFlagsOn(IsBlocked);
end;
SetLongFlag(beOptions,beBlockOn);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beMoveBlock;
var N,O,P,SP : LinePtr;
S,T : String;
begin
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) or
(NOT(beOptionsAreOn(beBlockOn))) then exit;
SBkTop := BkTop;
SBkBot := BkBot;
if BkTop.Line = BkBot.Line then begin
Tmp := BkTop.Line^.lnReturn;
S := Copy(Tmp,BkTop.Col,BkBot.Col-BkTop.Col+1);
Delete(Tmp,BkTop.Col,BkBot.Col-BkTop.Col+1);
BkTop.Line^.lnUpdate(Tmp);
Tmp := CurLine^.St^;
if COfs+XOfs > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1) + S
else
Insert(S,Tmp,COfs+XOfs);
CurLine^.lnUpdate(Tmp);
{update blocking}
BkTop.Line^.lnFlagsOff(IsBlocked);
BkTop.Line := CurLine;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkTop.Col := COfs+XOfs;
BkBot := BkTop;
BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
CurLine^.lnFlagsOn(IsBlocked);
end
else begin
SP := nil;
N := BkTop.Line;
Tmp := N^.lnReturn;
T := Copy(Tmp,BkTop.Col,Length(Tmp));
Delete(Tmp,BkTop.Col,Length(Tmp));
if Tmp = '' then
SP := N
else
N^.lnUpdate(Tmp);
P := CurLine;
Tmp := P^.lnReturn;
if COfs+XOfs <= Length(Tmp) then begin
S := Copy(Tmp,COfs+XOfs,Length(Tmp));
Delete(Tmp,COfs+XOfs,Length(Tmp));
end
else begin
if COfs+XOfs-1 > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1);
S := '';
end;
{set BlockTop to our new starting point}
BkTop.Line := P;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkBot.LNum := BkTop.LNum;
BkTop.Col := COfs+XOfs;
{walk the list, removing at old and inserting at new location}
Tmp := P^.St^ + T;
P^.lnUpdate(Tmp);
N^.lnFlagsOff(IsBlocked);
N := LinePtr(N^.dlNext);
while N <> BkBot.Line do begin
O := N;
N := LinePtr(N^.dlNext);
EList.Remove(O);
EList.Place(O,P);
P := LinePtr(P^.dlNext);
Inc(BkBot.LNum);
end;
{fixup the last line}
Tmp := Copy(BkBot.Line^.lnReturn,1,BkBot.Col);
BkBot.Line^.lnFlagsOff(IsBlocked);
BkBot.Col := Length(Tmp);
New(O,Init(Tmp+S));
O^.lnFlagsOn(IsBlocked);
EList.Place(O,P);
P := LinePtr(P^.dlNext);
Inc(BkBot.LNum);
Delete(Tmp,1,BkBot.Col);
BkBot.Line^.lnUpdate(Tmp);
BkBot.Line := P;
BkTop.Line^.lnFlagsOn(IsBlocked);
if SP <> nil then
EList.Delete(SP);
beResetSplit;
end;
SetLongFlag(beOptions,beBlockOn);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beDeleteBlock;
var S : String;
N,P : LinePtr;
I : Integer;
B : Boolean;
SvSplt : Integer;
function LineInBlock(P : LinePtr) : Boolean;
var N : LinePtr;
begin
LineInBlock := True;
N := BkTop.Line;
while (N <> LinePtr(BkBot.Line^.dlNext)) do begin
if P = N then exit;
N := LinePtr(N^.dlNext);
end;
LineInBlock := False;
end;
function BlockIsBetween : Boolean;
var P : LinePtr;
begin
BlockIsBetween := True;
P := CurTop;
while P <> CurLine do begin
if P = BkTop.Line then exit;
P := LinePtr(P^.dlNext);
end;
BlockIsBetween := False;
end;
begin
B := False;
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) or
(NOT(beOptionsAreOn(beBlockOn))) then begin
GotError(epNonFatal+ecNoBlock,'No block defined');
exit;
end;
P := BkTop.Line;
{if a single line, handle here}
if BkTop.Line = BkBot.Line then begin
S := P^.lnReturn;
Delete(S,BkTop.Col,BkBot.Col-BkTop.Col+1);
P^.lnUpdate(S);
P^.lnFlagsOff(IsBlocked);
beResetMarkers(False);
if CurLine = P then begin
beCursorHome;
beCursorRight(BkTop.Col-1);
end;
end
else with EList do begin
if LineInBlock(CurTop) then begin
CurTop := BkTop.Line;
CurTopIdx := BkTop.LNum;
if LineInBlock(CurLine) then begin
CurLine := CurTop;
CurLineOfs := 0;
beCursorHome;
beCursorRight(BkTop.Col - 1);
end
else B := True;
end
else if LineInBlock(CurLine) then begin
P := CurTop;
CurLine := BkTop.Line;
CurLineOfs := 0;
while (P <> CurLine) and (CurLineOfs < Height-1) do begin
Inc(CurLineOfs);
P := LinePtr(P^.dlNext);
end;
beCursorHome;
beCursorRight(BkTop.Col - 1);
end
else B := BlockIsBetween;
P := BkTop.Line;
S := P^.lnReturn;
System.Delete(S,BkTop.Col,Length(S));
P^.lnUpdate(S);
P := BkBot.Line;
S := P^.lnReturn;
System.Delete(S,1,BkBot.Col);
SvSplt := 1;
P^.lnUpdate(S);
P := LinePtr(BkTop.Line^.dlNext);
while P <> BkBot.Line do begin
Inc(SvSplt);
EList.Delete(P);
P := LinePtr(BkTop.Line^.dlNext);
end;
P := BkTop.Line;
beJoinLines(P);
end;
beResetSplit;
if B then
beLineUp(SvSplt);
beResetMarkers(False);
ClearLongFlag(beOptions,beBlockOn+beBlockOK);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beInsertBlockAtCursor(var FromList : LineList);
var P,N,O : LinePtr;
B : Boolean;
S : String;
begin
if (FromList.Size = 0) then begin
GotError(epNonFatal+ecNoBlock,'No block defined');
exit;
end;
P := CurLine;
if FromList.Head = FromList.Tail then begin
{a partial line to insert in the current line}
S := LinePtr(FromList.Head)^.lnReturn;
Tmp := CurLine^.St^;
if COfs+XOfs > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1) + S
else
Insert(S,Tmp,COfs+XOfs);
CurLine^.lnUpdate(Tmp);
{update blocking}
beClearBlocking;
BkTop.Line := CurLine;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkTop.Col := COfs+XOfs;
BkBot := BkTop;
BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
CurLine^.lnFlagsOn(IsBlocked);
end
else begin
Tmp := P^.lnReturn;
{if needed, split the current line}
if COfs+XOfs <= Length(Tmp) then begin
S := Copy(Tmp,COfs+XOfs,Length(Tmp));
Delete(Tmp,COfs+XOfs,Length(Tmp));
end
else begin
if COfs+XOfs-1 > Length(Tmp) then
Tmp := Pad(Tmp,COfs+XOfs-1);
S := '';
end;
{set BlockTop to our new starting point}
BkTop.Line := P;
BkTop.LNum := CurTopIdx+CurLineOfs;
BkBot.LNum := BkTop.LNum;
BkTop.Col := COfs+XOfs;
{walk the list, inserting lines}
N := LinePtr(FromList.Head);
Tmp := P^.St^ + N^.St^;
P^.lnUpdate(Tmp);
N := LinePtr(N^.dlNext);
while N <> NIL do begin
New(O,Init(N^.St^));
EList.Place(O,P);
P := LinePtr(P^.dlNext);
N := LinePtr(N^.dlNext);
Inc(BkBot.LNum);
end;
{set BlockBot to our ending line}
BkBot.Line := P;
BkBot.Col := BkBot.Line^.lnLen;
{if needed, merge in the tail of the split top line}
if S <> '' then begin
Tmp := P^.lnReturn;
P^.lnUpdate(Tmp+S);
end;
{reset things}
beClearBlocking;
beConnectMarks;
end;
SetLongFlag(beOptions,beBlockOn);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beReadBlock;
var F : Text;
FHandle : Word;
FName : PathStr;
P,N : LinePtr;
begin
FName := '';
if not beGetFileName(epMessage+mcBlockWrite, emBlockWrite,
FName, True, False) then
Exit;
Assign(F,FName);
Reset(F);
if IOResult <> 0 then begin
GotError(epNonFatal+ecFileNotFound,'File not found');
exit;
end
else if HandleIsConsole(FHandle) then begin
Close(F); if IOResult = 0 then ;
GotError(epNonFatal+ecNotToScreen,'Cannot read file from screen');
exit;
end;
TmpList.Clean;
while NOT EOF(F) do begin
ReadLn(F,Tmp);
if IOResult = 0 then begin
New(P,Init(Tmp));
if P = NIL then begin
GotError(epNonFatal+ecOutofMemory,'Out of memory');
Close(F); if IOResult = 0 then ;
exit;
end;
TmpList.Append(P);
end;
end;
{assure block marks are not equal}
BkTop.Line := CurTop;
BkBot.Line := NIL;
beInsertBlockAtCursor(TmpList);
SetLongFlag(beOptions,beBlockOn);
SetLongFlag(beOptions,beModified);
beForceRedraw := True;
end;
procedure BigEditor.beWriteBlock(ToPrn : Boolean);
var F : Text;
FHandle : Word absolute F;
FName : PathStr;
I : Integer;
P : LinePtr;
begin
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) then exit;
if ToPrn then begin
FName := 'LPT1';
Inc(FName[4], Pred(beLPT));
end
else begin
FName := '';
if not beGetFileName(epMessage+mcBlockWrite, emBlockWrite,
FName, True, False) then
Exit;
end;
Assign(F, FName);
Rewrite(F);
I := IOResult;
if I <> 0 then begin
GotError(epNonFatal+I, emOpenError);
Close(F);
I := IOResult;
Exit;
end
else if HandleIsConsole(FHandle) then begin
GotError(epNonFatal+ecNotToScreen, emNotToScreen);
Exit;
end;
if NOT beStoreBlock(TmpList) then exit;
with TmpList do begin
if Size = 0 then exit;
P := LinePtr(Head);
while P <> nil do begin
WriteLn(F,P^.lnReturn);
if IOResult <> 0 then begin
GotError(epNonFatal+ecDeviceWrite, 'Error writing block');
P := nil;
end
else
P := LinePtr(P^.dlNext);
end;
Close(F); if IOResult = 0 then ;
beInformation(0,'');
end;
end;
procedure BigEditor.beIndentBlock(AddSp : Boolean);
var P : LinePtr;
function CursorInBlock : Boolean;
var N : LinePtr;
begin
CursorInBlock := True;
N := BkTop.Line;
while N <> LinePtr(BkBot.Line^.dlNext) do begin
if N = CurLine then exit;
N := LinePtr(N^.dlNext);
end;
CursorInBlock := False;
end;
begin
beCheckBlock;
if (NOT(beOptionsAreOn(beBlockOK))) or
(NOT(beOptionsAreOn(beBlockOn))) then begin
GotError(epNonFatal+ecNoBlock,'No block defined');
exit;
end;
if NOT(CursorInBlock) then exit;
P := BkTop.Line;
if P = BkBot.Line then exit;
Tmp := P^.lnReturn;
if P^.lnLen > 0 then begin
if AddSp then begin
Insert(CharStr(' ',DefBlockIndent),Tmp,BkTop.Col);
if BkTop.Col > 1 then Inc(BkTop.Col,DefBlockIndent);
end
else begin
Delete(Tmp,BkTop.Col,DefBlockIndent);
if BkTop.Col > DefBlockIndent then
Dec(BkTop.Col,DefBlockIndent)
else
BkTop.Col := 1;
end;
P^.lnUpdate(Tmp);
end;
P := LinePtr(P^.dlNext);
while (P <> NIL) and (P <> BkBot.Line) do begin
Tmp := P^.lnReturn;
if P^.lnLen > 0 then begin
if AddSp then
Insert(CharStr(' ',DefBlockIndent),Tmp,1)
else
Delete(Tmp,1,DefBlockIndent);
P^.lnUpdate(Tmp);
end;
P := LinePtr(P^.dlNext);
end;
if (P <> NIL) and (P^.lnLen > 0) then begin
Tmp := P^.lnReturn;
if (AddSp) then begin
if (BkBot.Col > 0) then begin
Insert(CharStr(' ',DefBlockIndent),Tmp,1);
Inc(BkBot.Col,DefBlockIndent);
end;
end
else begin
Delete(Tmp,1,DefBlockIndent);
if BkBot.Col >= DefBlockIndent then
Dec(BkBot.Col,DefBlockIndent)
else
BkBot.Col := 0;
end;
P^.lnUpdate(Tmp);
end;
if AddSp then
beCursorRight(DefBlockIndent)
else
beCursorLeft(DefBlockIndent);
beForceRedraw := True;
SetLongFlag(beOptions,beModified);
end;
procedure BigEditor.beBlockWord;
var P : LinePtr;
W,X : Integer;
begin
W := COfs+XOfs;
Tmp := TrimTrail(CurLine^.lnReturn);
if W > Length(Tmp) then exit;
if Tmp[w] = ' ' then begin
{find the start of the next word}
while (W <= Length(Tmp)) and (Tmp[w] = ' ') do
Inc(W);
if W > Length(Tmp) then exit;
end
else
{find the start of the current word}
while (W > 1) and (Tmp[w-1] <> ' ') do Dec(W);
BkTop.Line := CurLine;
BkTop.Col := W;
{find the end of the current word}
while (W <= Length(Tmp)) and (Tmp[w+1] <> ' ') do
Inc(W);
BkBot.Line := CurLine;
BkBot.Col := W;
beClearBlocking;
CurLine^.lnFlagsOn(IsBlocked);
beOptionsOn(beBlockOn);
beForceRedraw := True;
end;
procedure BigEditor.beChangeCaseBlock(Cmd : Byte);
{-Change the case of all characters in block or of character at cursor}
var
P : LinePtr;
function ToggleCase(Ch : Char) : Char;
{-Toggle the case of the specified character}
var
NewCh : Char;
begin
NewCh := UpCase(Ch);
if NewCh <> Ch then
ToggleCase := NewCh
else
ToggleCase := Locase(Ch);
end;
procedure FixChar(var Ch : Char);
{-Fix the case of Ch based on the user's command}
begin
if Ch > ' ' then
case Cmd of
ccBlkUCase : Ch := UpCase(Ch);
ccBlkLCase : Ch := LoCase(Ch);
ccBlkTCase : Ch := ToggleCase(Ch);
end;
end;
procedure FixLine(P : LinePtr; Start, Stop : Integer);
var
TLen : Byte;
I : Integer;
begin
TLen := P^.lnLen;
for I := Start to Stop do
if I <= TLen then
FixChar(P^.St^[i]);
end;
begin
if (LongFlagIsSet(beOptions, beBlockOn)) and
(beLineInBlock(CurLine)) then begin
if BkTop.Line = BkBot.Line then
FixLine(CurLine,BkTop.Col,BkBot.Col)
else begin
P := BkTop.Line;
FixLine(P,BkTop.Col,P^.lnLen);
IncPtr(P,1);
while P <> BkBot.Line do begin
FixLine(P,1,P^.lnLen);
IncPtr(P,1);
end;
FixLine(P,1,BkBot.Col);
beForceRedraw := True;
end;
SetLongFlag(beOptions,beModified);
end
else if (COfs+COfs <= CurLine^.lnLen) then begin
{change the case of the character at the cursor}
FixChar(CurLine^.St^[COfs+XOfs]);
SetLongFlag(beOptions,beModified);
end;
end;
procedure BigEditor.beCopyToClipboard;
begin
if beStoreBlock(Clipboard) then begin
beOptionsOff(beBlockOn);
beForceRedraw := True;
end;
end;
procedure BigEditor.beCutToClipboard;
begin
if beStoreBlock(Clipboard) then begin
beDeleteBlock;
beForceRedraw := True;
end;
end;
procedure BigEditor.bePasteFromClipboard;
begin
if Clipboard.Head <> NIL then
beInsertBlockAtCursor(Clipboard);
end;
{--------------------- Search/Replace/Reformat stuff -----------------------}
procedure BigEditor.beTextSearch(Prompt : Boolean; SearchType : beSearchType);
label ExitPoint;
var
SaveRec : StreamStateRec;
SaveIdx : Integer;
Hits : Integer;
TSrch : String[MaxSearchLen];
N : Integer;
YN : Byte;
procedure ReplaceText(var Cur : String; Repl : String; Start, Len : Integer);
begin
Delete(Cur,Start,Len);
Insert(Repl,Cur,Start);
end;
function NextMatch(StartLine : LinePtr; Srch : String) : LinePtr;
var P : LinePtr;
T : String;
begin
NextMatch := NIL;
P := StartLine;
if P <> NIL then begin
if NoCase then
Tmp := StUpcase(P^.lnReturn)
else
Tmp := P^.lnReturn;
if Backwards then begin
while P <> NIL do begin
while SaveIdx >= 1 do begin
if Srch[1] = Tmp[SaveIdx] then begin {possible match}
T := Copy(Tmp,SaveIdx,Length(Srch));
if T = Srch then begin {positive match}
NextMatch := P;
exit;
end;
end;
Dec(SaveIdx);
end;
P := LinePtr(EList.Prev(P));
if P <> NIL then begin
Dec(CurTopIdx);
beStatusProc(@Self);
SaveIdx := P^.lnLen;
if NoCase then
Tmp := StUpcase(P^.lnReturn)
else
Tmp := P^.lnReturn;
end;
end;
end
else begin
while P <> NIL do begin
while SaveIdx <= Length(Tmp) do begin
if Srch[1] = Tmp[SaveIdx] then begin {possible match}
T := Copy(Tmp,SaveIdx,Length(Srch));
if T = Srch then begin {positive match}
NextMatch := P;
exit;
end;
end;
Inc(SaveIdx);
end;
P := LinePtr(EList.Next(P));
if P <> NIL then begin
Inc(CurTopIdx);
beStatusProc(@Self);
SaveIdx := 1;
if NoCase then
Tmp := StUpcase(P^.lnReturn)
else
Tmp := P^.lnReturn;
end;
end;
end;
end;
end;
begin
{if a reSearch and no prev search performed, quit}
if (NOT(Prompt)) and (SearchType = bescSearch) and (beSearchLine = NIL) then
exit;
if (Prompt) then begin
if NOT beGetString(0,'Search for: ',False,False,MaxSearchLen,beSearchSt) then
exit;
if (SearchType = bescReplace) then begin
if NOT beGetString(0,'Replace with: ',False,False,MaxSearchLen,beReplaceSt) then
exit;
end;
if NOT beGetString(0,'Options: ',True,True,MaxSearchOptions,beOptionSt) then
exit;
beReplacements := 0;
NoCase := False;
Backwards := False;
NoConfirm := False;
BlockOnly := False;
Global := False;
for N := 1 to Length(beOptionSt) do
case Upcase(beOptionSt[N]) of
beBackward : Backwards := True;
beNoCase : NoCase := True;
beNoConfirm : NoConfirm := True;
beBlockOnly : BlockOnly := True;
beGlobal : Global := Prompt and not(LongFlagIsSet(beOptions,beNoRepeatGlobal));
end;
end;
beSaveStreamState(SaveRec,False);
SetLongFlag(beOptions,beSearching);
if NoCase then
TSrch := StUpCase(beSearchSt)
else
TSrch := beSearchSt;
if Backwards then
ClearLongFlag(beOptions,beHighlightBack)
else
SetLongFlag(beOptions,beHighlightBack);
beSearchLine := CurLine;
if Backwards then
SaveIdx := COfs+XOfs-1
else
SaveIdx := COfs+XOfs;
{adjust so Curline is the top-of-screen}
CurTopIdx := CurTopIdx+CurLineOfs;
if (Prompt) and (Global) then begin
if Backwards then begin
beSearchLine := LinePtr(EList.Tail);
CurTopIdx := EList.Size;
SaveIdx := beSearchLine^.lnLen;
end
else begin
beSearchLine := LinePtr(EList.Head);
CurTopIdx := 1;
SaveIdx := 1;
end;
end;
YN := beYes;
Hits := 0;
while True do begin
CurLineOfs := 0;
beSearchLine := NextMatch(beSearchLine,TSrch);
if (beSearchLine = NIL) or
((BlockOnly) and (NOT(beLineInBlock(beSearchLine)))) then begin
GotError(epNonFatal+ecStringNotFound,'No match found');
goto ExitPoint;
end;
Inc(Hits);
{make it displayable}
CurLine := beSearchLine;
CurTop := CurLine;
CurLineOfs := 0;
COfs := 1;
XOfs := 0;
{try to center the line in the screen}
while (CurTop^.dlPrev <> NIL) and (CurLineOfs < (Height div 2)) do begin
CurTop := LinePtr(EList.Prev(CurTop));
Dec(CurTopIdx);
Inc(CurLineOfs);
end;
{position the cursor}
if Backwards then
beCursorRight(SaveIdx-1)
else
beCursorRight(SaveIdx+Length(beSearchSt)-1);
beForceRedraw := True;
beInformation(0,'');
SetLongFlag(beOptions,beShowMkrs);
beUpdateContents;
beSaveStreamState(SaveRec,False);
if SearchType = bescSearch then begin
while NOT cwCmdPtr^.cpKeyPressed do ;
goto ExitPoint;
end
else begin
if NOT NoConfirm then begin
YN := beYesNo(0,'Replace?',beNo,True);
NoConfirm := (YN = beAll);
if (YN = beQuit) then
goto ExitPoint;
end;
if YN <> beNo then begin
Tmp := CurLine^.lnReturn;
ReplaceText(Tmp,beReplaceSt,SaveIdx,Length(beSearchSt));
CurLine^.lnUpdate(Tmp);
inc(beReplacements);
ClearLongFlag(beOptions,beShowMkrs);
beForceRedraw := True;
beUpdateContents;
end;
CurTopIdx := CurTopIdx+CurLineOfs;
if Backwards then
Dec(SaveIdx)
else if Length(beReplaceSt) > Length(beSearchSt) then
Inc(SaveIdx,Length(beReplaceSt))
else
Inc(SaveIdx,Length(beSearchSt));
end;
end;
ExitPoint:
beRestoreStreamState(SaveRec,False);
if beReplacements > 0 then
SetLongFlag(beOptions,beModified);
if (SearchType = bescReplace) and (beReplacements > 0) then
beInformation(0,' Replacements: '+Long2Str(beReplacements));
ClearLongFlag(beOptions,beSearching);
beUpdateContents;
end;
procedure BigEditor.beReformatPara;
label BrkOut;
var B : Byte;
P,N : LinePtr;
S : String;
begin
if NOT beOptionsAreOn(beWordWrap) then exit;
SetLongFlag(beOptions,beReformatting);
while (CurLine^.dlNext <> NIL) and (CurLine^.St^ = '') do
beLineDown(1);
if CurLine^.dlNext = NIL then exit;
B := beOfsWhite(CurLine);
P := CurLine;
{run the loop}
while (P <> NIL) and (P^.lnLen > 0) do begin
while (P^.lnLen <= Margin+1) and (LinePtr(P^.dlNext)^.lnLen > 0) do begin
N := LinePtr(P^.dlNext);
if N = nil then goto BrkOut;
Tmp := N^.lnReturn;
Tmp := ' '+Trim(Tmp);
P^.lnUpdate(P^.lnReturn+Tmp);
EList.Delete(N);
end;
WordWrap(P^.lnReturn,Tmp,S,Margin,False);
Tmp := Trim(Tmp);
if B > 0 then
Insert(CharStr(' ',B),Tmp,1);
P^.lnUpdate(Tmp);
S := Trim(S);
if S <> '' then begin
if B > 0 then
Insert(CharStr(' ',B),S,1);
New(N,Init(S));
EList.Place(N,P);
end;
P := LinePtr(P^.dlNext);
end;
BrkOut:
CurLine := P;
beRealignDown;
beCursorHome;
beCursorRight(CurLine^.lnLen);
ClearLongFlag(beOptions,beReformatting);
SetLongFlag(beOptions,beModified);
beCheckBlock;
if beOptionsAreOn(beBlockOK) then begin
beClearBlocking;
beResetMarkers(False);
beOptionsOff(beBlockOn);
end;
beForceRedraw := True;
end;
procedure BigEditor.beReformatGlobally;
var S : StreamStateRec;
begin
beSaveStreamState(S,False);
while CurLine^.dlNext <> nil do begin
beReformatPara;
beUpdateContents;
end;
beRestoreStreamState(S,False);
end;
procedure BigEditor.beCenterLine;
var
StLen : Byte absolute Current;
I, J, Delta, Len : Integer;
begin
if StLen = 0 then
Exit;
{find the first non-blank}
I := 1;
while Current[I] = ' ' do
Inc(I);
{length of actual text in string}
Len := Succ(StLen-I);
{can it be centered?}
if Len >= Margin then begin
if I > 1 then begin
{can't center it, but we can move it to the left margin}
Delete(Current, 1, Pred(I));
beCharsInserted(CurLine, -Pred(I));
{adjust cursor}
if COfs+XOfs >= I then
beCursorLeft(Pred(I))
else
beCursorHome;
end;
end
else begin
{calculate new starting column}
J := Succ((Margin-Len) shr 1);
Delta := J-I;
if Delta > 0 then begin
{insert extra spaces at beginning of line}
Insert(CharStr(' ', Delta), Current, 1);
beCharsInserted(CurLine, Delta);
{adjust cursor}
beCursorRight(Delta);
end
else if Delta < 0 then begin
{delete extra spaces at beginning of line}
Delete(Current, 1, -Delta);
beCharsInserted(CurLine, -Delta);
{adjust cursor}
if COfs+XOfs > Abs(Delta) then
beCursorRight(Delta)
else
beCursorHome;
end;
end;
CurLine^.lnUpdate(Current);
SetLongFlag(beOptions,beModified);
end;